package org.example.sb_api.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.sb_api.common.Result;
import org.example.sb_api.dto.LoginDTO;
import org.example.sb_api.dto.RegisterDTO;
import org.example.sb_api.entity.User;
import org.example.sb_api.mapper.UserMapper;
import org.example.sb_api.service.UserService;
import org.example.sb_api.util.JwtUtil;
import org.example.sb_api.util.MD5Util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.example.sb_api.util.CommonUtil;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;
    
    // 验证码过期时间(分钟)
    private static final long CODE_EXPIRE_MINUTES = 5;
    
    // Redis验证码key前缀
    private static final String CODE_KEY_PREFIX = "verification_code:";

    @Override
    public Result phoneLogin(LoginDTO loginDTO) {
        // 验证手机号格式
        if (!CommonUtil.isValidPhone(loginDTO.getPhone())) {
            return Result.error(400, "手机号格式不正确");
        }
        
        // 验证手机号和验证码
        if (!verifyCode(loginDTO.getPhone(), loginDTO.getCode())) {
            return Result.error(400, "验证码错误或已过期");
        }
        
        // 查询用户
        User user = userMapper.selectOne(
            new QueryWrapper<User>().eq("phone", loginDTO.getPhone())
        );
        
        // 如果用户不存在，则自动注册
        if (user == null) {
            user = new User();
            user.setPhone(loginDTO.getPhone());
            user.setNickName("用户" + loginDTO.getPhone().substring(7)); // 默认昵称为"用户"+手机号后4位
            userMapper.insert(user);
        }
        
        // 生成token
        String token = JwtUtil.generateToken(user.getId());
        
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("tokenmsg", "Bearer " + token);
        result.put("code", 200);
        result.put("userId", user.getId());
        result.put("nickName", user.getNickName());
        result.put("phone", user.getPhone());
        
        return Result.success(result);
    }

    @Override
    public Result register(RegisterDTO registerDTO) {
        // 判断注册方式
        if (registerDTO.getPhone() != null && registerDTO.getCode() != null) {
            // 手机号注册
            return registerByPhone(registerDTO);
        } else if (registerDTO.getUsername() != null && registerDTO.getPassword() != null) {
            // 用户名密码注册
            return registerByUsername(registerDTO);
        } else {
            return Result.error(400, "注册参数不完整");
        }
    }

    // 手机号注册
    private Result registerByPhone(RegisterDTO registerDTO) {
        // 验证手机号格式
        if (!CommonUtil.isValidPhone(registerDTO.getPhone())) {
            return Result.error(400, "手机号格式不正确");
        }
        
        // 验证手机号和验证码
        if (!verifyCode(registerDTO.getPhone(), registerDTO.getCode())) {
            return Result.error(400, "验证码错误或已过期");
        }
        
        // 检查手机号是否已注册
        User existUser = userMapper.selectOne(
            new QueryWrapper<User>().eq("phone", registerDTO.getPhone())
        );
        
        if (existUser != null) {
            return Result.error(400, "该手机号已注册");
        }
        
        // 创建新用户
        User user = new User();
        user.setPhone(registerDTO.getPhone());
        user.setNickName(registerDTO.getNickName() != null ? 
            registerDTO.getNickName() : "用户" + registerDTO.getPhone().substring(7));
        user.setEmail(registerDTO.getEmail());
        
        userMapper.insert(user);
        return Result.success(null);
    }

    // 用户名密码注册
    private Result registerByUsername(RegisterDTO registerDTO) {
        // 验证用户名密码
        if (registerDTO.getUsername() == null || registerDTO.getUsername().length() < 4) {
            return Result.error(400, "用户名长度不能小于4位");
        }
        if (registerDTO.getPassword() == null || registerDTO.getPassword().length() < 6) {
            return Result.error(400, "密码长度不能小于6位");
        }
        
        // 如果提供了手机号，验证格式
        if (registerDTO.getPhone() != null && !CommonUtil.isValidPhone(registerDTO.getPhone())) {
            return Result.error(400, "手机号格式不正确");
        }
        
        // 检查用户名是否已存在
        User existUser = userMapper.selectOne(
            new QueryWrapper<User>().eq("username", registerDTO.getUsername())
        );
        
        if (existUser != null) {
            return Result.error(400, "该用户名已存在");
        }
        
        // 如果提供了手机号，检查是否已被使用
        if (registerDTO.getPhone() != null) {
            existUser = userMapper.selectOne(
                new QueryWrapper<User>().eq("phone", registerDTO.getPhone())
            );
            if (existUser != null) {
                return Result.error(400, "该手机号已被使用");
            }
        }
        
        // 创建新用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(MD5Util.encode(registerDTO.getPassword()));
        user.setPhone(registerDTO.getPhone());  // 可以为null
        user.setNickName(registerDTO.getNickName() != null ? 
            registerDTO.getNickName() : registerDTO.getUsername());
        user.setEmail(registerDTO.getEmail());
        
        userMapper.insert(user);
        return Result.success(null);
    }

    @Override
    public Result login(LoginDTO loginDTO) {
        User user = userMapper.selectOne(
            new QueryWrapper<User>()
                .eq("username", loginDTO.getUsername())
        );
        
        if (user == null || !user.getPassword().equals(MD5Util.encode(loginDTO.getPassword()))) {
            return Result.error("用户名或密码错误");
        }
        
        String token = JwtUtil.generateToken(user.getId());
        
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("tokenmsg", "Bearer " + token);
        map.put("code", 200);
        
        return Result.success(map);
    }

    @Override
    public Result getVerificationCode(String phone) {
        // 生成6位随机验证码
        String code = String.format("%06d", new Random().nextInt(1000000));
        
        // 将验证码存储到Redis,设置过期时间
        String key = CODE_KEY_PREFIX + phone;
        redisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        
        // TODO: 调用短信服务发送验证码
        // 这里模拟发送验证码
        log.info("Send verification code {} to phone {}", code, phone);
        
        return Result.success(code);
    }

    private boolean verifyCode(String phone, String code) {
        if (phone == null || code == null) {
            return false;
        }
        
        // 从Redis获取验证码
        String key = CODE_KEY_PREFIX + phone;
        String savedCode = redisTemplate.opsForValue().get(key);
        
        // 验证码匹配且未过期
        if (code.equals(savedCode)) {
            // 验证通过后删除验证码
            redisTemplate.delete(key);
            return true;
        }
        
        return false;
    }
} 